#include <modbus.h>
#include <stdio.h>
#include <string.h>
#include "cJSON.h"
#include <pthread.h>
#include "shmem.h"
#include "msg_queue_peer.h"


int flag1 = 1;
int flag2 = 1;
data_t *SlaveData;     // 定义存放从机数据的结构体
struct shm_param para; // 定义共享内存结构体

void* msg_request(void *arg) // 子线程用于处理消息队列数据
{
    modbus_t * ctx = (modbus_t *)arg;
    int key_val;
    char recv_buf[128];
    while(1)
    {
    msg_queue_recv("msg1", recv_buf, sizeof(recv_buf), 0, 0);
    printf("recv_buf: %s\n", recv_buf);
    cJSON *root = cJSON_Parse(recv_buf);
    if (root == NULL)
    {
        // 解析失败，打印错误信息
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            fprintf(stderr, "JSON 解析错误在: %s\n", error_ptr);
        }
        return NULL;
    }

    // 提取 "data" 对象
    cJSON *data_item = cJSON_GetObjectItem(root, "data");
    // 从 "data" 里提取 "val"
    cJSON *val_item = cJSON_GetObjectItem(data_item, "val");
    // 从 "data" 里提取 "key"
    cJSON *key_item = cJSON_GetObjectItem(data_item, "key");
        if(strcmp(val_item->valuestring,"true") == 0)
            key_val = 1;
        else
            key_val = 0;
        printf("data.key: %d\n", key_val);
        if (key_item->valueint == 301)
        {
            modbus_write_bit(ctx,0,key_val);
        }
        if (key_item->valueint == 302)
        {
            modbus_write_bit(ctx,1,key_val);
        }
    // 释放 cJSON 解析后占用的内存
    cJSON_Delete(root);
    }

}

int main(int argc, char const *argv[])
{
   
    char buff[1024] = "";
    uint8_t buf[2] = {0};
    FILE *fd = fopen("/home/hq/work/007/data_report/config.json", "r");
    if (NULL == fd)
    {
        perror("err!");
        return -1;
    }
    fread(buff, 4024, 1, fd);
    cJSON *root1 = cJSON_Parse(buff);                     // 根节点
    cJSON *mb_dev = cJSON_GetObjectItem(root1, "mb_dev"); // mb_dev节点
    cJSON *addr = cJSON_GetObjectItem(mb_dev, "addr");
    printf("%s:%s\n", addr->string, addr->valuestring);
    cJSON *port = cJSON_GetObjectItem(mb_dev, "port");
    printf("%s:%d\n", port->string, port->valueint);
    cJSON *stm32 = cJSON_GetObjectItem(root1, "stm32");
    // printf("------------%d\n", __LINE__);
    cJSON *data = cJSON_GetObjectItem(stm32, "data");
    // printf("------------%d\n", __LINE__);
    // 获取data数组节点的元素个数
    int stm32_num = cJSON_GetArraySize(data);
    printf("%d\n", stm32_num);
    cJSON *modbus = cJSON_GetObjectItem(root1, "modbus");
    cJSON *data1 = cJSON_GetObjectItem(modbus, "data");
    int modbus_num = cJSON_GetArraySize(data1);
    printf("%d\n", modbus_num);
    int sum = stm32_num + modbus_num;
    // 绑定服务器的IP，端口号
    modbus_t *ctx = modbus_new_tcp(addr->valuestring, port->valueint);
    if (ctx == NULL)
    {
        perror("创建失败");
        return -1;
    }
    printf("服务器已搭建！\n");

    // 从机ID
    int a = modbus_set_slave(ctx, 1);
    if (a < 0)
    {
        perror("SET_Slave Err");
        return -1;
    }
    int con = modbus_connect(ctx);
    if (con < 0)
    {
        perror("Connet Err");
        return -1;
    }
    printf("从机链接成功！success\n");
    pthread_t tid = pthread_create(&tid, NULL, msg_request, ctx);
    
    while (1)
    { 
        int read = modbus_read_bits(ctx, 0, 2, buf);
        if (read < 0)
        {
            perror("Read Err");
            return -1;
        }
        sleep(1);
        if (flag1 == 1)
        {
            // 共享内存占用空间大小值
            size_t shm_size = sizeof(int) + sizeof(data_t) *sum;
            if (shm_init(&para, "shm", shm_size) < 0)
            {
                printf("shm init err\n");
                return -1;
            }
            // 获取共享内存的起始地址
            void *shm_base_addr = shm_getaddr(&para);
            if (shm_base_addr == (void *)-1 || shm_base_addr == NULL)
            {
                printf("shm get addr err\n");
                return -1;
            }
            data_t *std_array = (data_t *)((char *)shm_base_addr + sizeof(int) + (sizeof(data_t) *stm32_num));

            // 从第10个结构体开始，前9个是单片机的数据
            for (int i = 0; i < modbus_num; i++)
            {
                std_array[i].key = 300 + i;
                std_array[i].new_val.b_val = buf[i];
                std_array[i].ret = 0;
                if (std_array[i].old_val.b_val != std_array[i].new_val.b_val)
                {
                    printf("%d\n", std_array[i].new_val.b_val);
                    std_array[i].old_val.b_val = std_array[i].new_val.b_val;
                    printf("数据已上传\n");
                }
                
            }
        }
        pthread_join(tid, NULL);
    }

    modbus_close(ctx);
    modbus_free(ctx);
    
    return 0;
}
